﻿/*
*┌────────────────────────────────────────────────┐
*│　描    述：DapperDBContex                                                   
*│　作    者： (Jxw)                                             
*│　版    本：1.0     
*│　功能描述：                                          
*│　创建时间：2021/4/25 11:13:36                        
*└────────────────────────────────────────────────┘
*/

using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Utility;

namespace Data
{
    public static class DapperDBContext
    {
        public static List<T> AsList<T>(this IEnumerable<T> source)
        {
            if (source != null && !(source is List<T>))
                return source.ToList();
            return (List<T>)source;
        }
        //参数我们跟后台封装方法保持一致
        public static int Execute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null, int databaseOption = 1)
        {
            using (var conn = DapperDBHelper.InitConn())
            {
                var info = "SQL语句:" + sql + "  \n SQL参数: " + JsonHelper.SerializeObject(param) + " \n";
                // LogHelper.ErrorLog(info);   // 可以记录操作
                var sw = new Stopwatch(); sw.Start();
                var restult = conn.Execute(sql, param, transaction, commandTimeout, commandType);
                sw.Stop();
                LogUtility.Debug("DapperDBContext/Execute", info + "耗时:" + sw.ElapsedMilliseconds + (sw.ElapsedMilliseconds > 1000 ? "#####" : string.Empty) + "\n"); // 可以记录操作
                return restult;
            }
        }

        public static int Execute(CommandDefinition command, int databaseOption = 1)
        {
            using (var conn = DapperDBHelper.InitConn())
            {
                var info = " SQL语句:" + command.CommandText + "  \n SQL命令类型: " + command.CommandType + " \n";
                //  LogHelper.Info(info);// 可以记录操作
                var sw = new Stopwatch(); sw.Start();
                var restult = conn.Execute(command);
                sw.Stop();
                LogUtility.Debug("DapperDBContext/Execute", info + "耗时:" + sw.ElapsedMilliseconds + (sw.ElapsedMilliseconds > 1000 ? "#####" : string.Empty) + "\n"); // 可以记录操作
                return restult;
            }
        }


        /// <summary>
        /// 多表操作--事务
        /// </summary>
        /// <param name="trans"></param>
        /// <param name="databaseOption"></param>
        /// <param name="commandTimeout"></param>
        /// <returns></returns>
        public static Tuple<bool, string> ExecuteTransaction(List<Tuple<string, object>> trans, int databaseOption = 1, int? commandTimeout = null)
        {
            if (!trans.Any()) return new Tuple<bool, string>(false, "执行事务SQL语句不能为空！");
            using (var conn = DapperDBHelper.InitConn())
            {
                //开启事务
                using (var transaction = conn.BeginTransaction())
                {
                    try
                    {
                        var sb = new StringBuilder("ExecuteTransaction 事务： ");
                        foreach (var tran in trans)
                        {
                            sb.Append("SQL语句:" + tran.Item1 + "  \n SQL参数: " + JsonHelper.SerializeObject(tran.Item2) + " \n");
                            LogUtility.Debug("ExecuteTransaction", "SQL语句:" + tran.Item1 + "  \n SQL参数: " + JsonHelper.SerializeObject(tran.Item2) + " \n");
                            //执行事务
                            conn.Execute(tran.Item1, tran.Item2, transaction, commandTimeout);
                        }
                        var sw = new Stopwatch();
                        sw.Start();
                        //提交事务
                        transaction.Commit();
                        sw.Stop();
                        // 根据业务添加纪录日志 LogHelper.InfoLog(sb.ToString() + "耗时:" + sw.ElapsedMilliseconds + (sw.ElapsedMilliseconds > 1000 ?                        "#####" : string.Empty) + "\n");
                        return new Tuple<bool, string>(true, string.Empty);
                    }
                    catch (Exception ex)
                    {
                        //todo:!!!transaction rollback can not work.

                        LogUtility.Debug("ExecuteTransaction", ex.ToString());
                        //回滚事务
                        transaction.Rollback();
                        conn.Close();
                        conn.Dispose();
                        return new Tuple<bool, string>(false, ex.ToString());
                    }
                    finally
                    {
                        conn.Close();
                        conn.Dispose();
                    }
                }
            }
        }
    }
}
